读JDK源码,可以边读边加注释的姿势怎么样?
Editor's Note
JDK源码是面试必问的内容。多数童鞋读过之后总是忘记,下次读还要回忆当初的思考过程,如果可以一边读源码一边在源码上加自己的注释那是最好的,本文内容就能满足你的需求,一年下来,JDK源码变得沉甸甸的呢
The following article is from CodeSheep Author hansonwong99
为什么要读JDK源码
当然不是为了装,毕竟谁没事找事虐自己 ...
1、面试跑不掉。现在只要面试Java相关的岗位,肯定或多或少会会涉及JDK源码相关的问题。
2、弄懂原理才不慌。我们作为JDK的使用者,虽然说天天用得很开心,但是有时候遇到问题还是得跟到底层源码去看看,才能帮助我们更好的弄懂原理,
3、学习优秀的代码、思想和模式。JDK毕竟是一个优秀的代码库,我们天天用,源码也就在里面,作为一个有志向的程序员,读一读源码也能让我们吸取到更多优秀的思想和模式。
4、睡前催眠。额 …… 不过的确有效(滑稽)。
源码难吗?
废话,当然有难度啦,不然我也不会到现在都还没看完,而且看了也经常忘,哭唧唧...
毕竟像JDK这种源码,和我们平常练手写小例子、写业务代码不一样,人家毕竟是 类库,为了性能、稳定性、通用性,扩展性等因素考虑,加入了很多辅助代码、泛型、以及一些设计模式上的考量,所以看起来肯定没有那么轻松,没办法一眼看穿它。
所以这玩意儿肯定是一个长期的过程,我个人建议(包括我自己也是这样),有时候遇到一些问题,可以针对性地把某些组件或者某个部分的源码,跟到底层去看看,然后做点笔记,写点注释啥的,这样慢慢就能渗透到很多的内容了。
但是我们一定要有足够的信心,我坚信代码人家都写出来了,我就不信我看不懂!
源码该怎么看
1、方法一:按需阅读。如果对某个组件、语法或者特性感兴趣,或者遇到什么问题疑惑,可以有针对性地跟到底层源码按需查看,这也是一种比较高效,能快速树立信心的阅读方式。
2、方法二:系统化阅读。具体阅读内容和顺序建议下文详述。
3、多调试:如果仅仅靠眼睛看,然后脑补画面调试还是比较吃力的,最好还是借助IDE动手调试起来,走两步就知道了。
4、别光读,记得读完留下点什么。我觉得看了多少不重要,重要的是能输出多少,多总结、归纳,写注释,记笔记
所以下文准备搭建一个Java源码的阅读和调试环境,建议人手一个,每当心血来潮时、遇到问题时、碰到疑惑时、闲得无聊时都可以打开工程看一看源码,做做笔记和注释。
搭建源码阅读调试环境
我个人觉得看源码这个事情还是应该单独搞一个Java工程,源码放里面,测试代码也放里面,集中调试,集中看代码,集中写注释比较方便一些。
1、创建源码阅读项目
选择最普通的Java基础项目即可:
2、创建两个目录
分别为:
source
:稍后放置JDK源码进去test
:放置测试代码,里面还可以按需要建立层级子目录
3、导入JDK源码
有很多小伙伴问JDK的源码在哪里呢?
远在天边,仅在眼前,其实在的JDK安装目录下就能找到。
JDK安装目录下有一个名为src.zip
压缩包,这正是JDK源码!
将其解压后拷贝到上面项目的source
目录下,这样JDK源码就导入好了。
有些小伙伴会有疑问,为什么要将JDK源码导一份放到这个项目里?其实主要原因还是方便我们在源码里阅读、调试、以及做笔记和注释。
至于这份JDK源码怎么用上,下文继续阐述。
4、调试并运行
我们可以在test
目录里去随意编写一段测试代码。
比如我这里就以HashMap
为例,在test
目录下创建一个子目录hashmap
,然后在里面创建一个测试主入口文件Test.java
,随意放上一段测试代码:
public static void main( String[] args ) {
Map<String,Double> hashMap = new HashMap<>();
hashMap.put( "k1", 0.1 );
hashMap.put( "k2", 0.2 );
hashMap.put( "k3", 0.3 );
hashMap.put( "k4", 0.4 );
for ( Map.Entry<String,Double> entry : hashMap.entrySet() ) {
System.out.println( entry.getKey() +":" + entry.getValue());
}
}
然后启动调试即可。
不过接下来会有几个问题需要一一去解决。
问题一:启动调试时Build报错,提示系统资源不足
解决方法: 加大Build process heap size
。
设置方法:Preferences --> Build,Execution,Deployment --> Compiler
,将默认700
的数值加大,比如我这里设置为1700
:
问题二:想从外层代码F7单步调试进入JDK源码内部,结果发现进不去
这是因为调试时,JDK源码受保护,一般单步调试不让进,但是可以设置。
解决方法::
Preferences --> Build,Execution,Deployment --> Debugger --> Stepping
问题三:如何对JDK源码做注释?
调试进入JDK源码以后,发现不能进行注释,每个文件上都有一个小锁的图标,这是因为现在关联的源码并不是我们项目里刚拷进去的源码,而是JDK安装目录下的src.zip
只读压缩包。
解决办法: 重新关联JDK源码路径为本项目路径下的这一份JDK源码。
这样一来,我们就可以愉快地对JDK源码调试以及做注释了。
源码结构和阅读顺序
JDK源码毕竟太庞大了,所有都看不太现实,我们还是愿意根据日常使用和面试考察的频繁度来挖取重要的内容先看一看。
如果自己没有特别的规划,可以按照如下所示的建议阅读顺序往下进行:
具体的内容简介如下:
1、java.lang
这里面其实就是Java的基本语法,比如各种基本包装类型(Integer
、Long
、Double
等)、基本类(Object
,Class
,Enum
,Exception
,Thread
)等等...
2、java.lang.annotation
包含Java注解基本元素相关的源码
3、java.lang.reflect
包含Java反射基本元素相关的代码
4、java.util
这里面放的都是Java的基本工具,最典型和常用的就是各种容器和集合(List
、Map
、Set
)
5、java.util.concurrent
大名鼎鼎的JUC包,里面包含了Java并发和多线程编程相关的代码
6、java.util.function
+java.util.stream
包含Java函数式编程的常见接口和代码
7、java.io
包含Java传统I/O相关的源码,主要是面向字节和流的I/O
8、java.nio
包含Java非阻塞I/O相关的源码,主要是面向缓冲、通道以及选择器的I/O
9、java.time
包含Java新日期和期间相关的代码,最典型的当属LocalDateTime
、DateTimeFormatter
等
10、java.math
主要包含一些高精度运算的支持数据类
11、java.math
主要包含一些高精度运算的支持数据类
12、java.net
主要包含Java网络通信(典型的如:Socket
通信)相关的源代码。
共勉
看源码这东西不能急,慢一点才能更快!共勉。
HTTP灵魂拷问,你了解你的每次请求吗?
这么说线程生命周期是不是简单了点?
超强图文|并发编程【等待/通知机制】就是这个feel~